package com;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 罗俊华
 * @date 2021/8/24 - 5:52 下午
 */
@Slf4j
public class HelloServer {

    public static void main(String[] args) {
        new ServerBootstrap()
//                1、EventGroup：一个 thread 和 一个 selector 组合形成一个 eventGroup
//                NioEventGroup： 相当于nio章节的 boosEventGroup 和 workerEventGroup
                .group(new NioEventLoopGroup())
//                2、配置 serverSocketChannel 的具体实现
//                Oio 也就是 Bio
//                nio 对原生的 ServerSocketChannel 进行了封装，叫做 NioServerSocketChannel
                .channel(NioServerSocketChannel.class)
//                3、bossEventGroup 负责 accept 连接
//                workerEventGroup 负责处理读写，也就是 childHandler() 负责处理的具体业务逻辑
                .childHandler(
//                        4、代表和客户端进行读写的数据通道，ChannelInitializer 负责添加别的 handler
//
                        new ChannelInitializer<NioSocketChannel>() {
                            /**
                             * 只有在 accept 事件触发之后才会开始执行 initChannel()
                             * @param ch
                             * @throws Exception
                             */
                            @Override
                            protected void initChannel(NioSocketChannel ch) throws Exception {
//                              5、添加具体的 handler，网络中传输的数据都是以字节的形式传输，
//                                在netty中用 byteBuf 进行表示，
//                                StringDecoder 是为了将 byteBuf 转换（解码）为 字符串
                                ch.pipeline().addLast(new StringDecoder());
//                                6、添加自定义的 handler
                                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

                                    /**
                                     * 接收到数据包，读事件触发时调用
                                     * @param ctx
                                     * @param msg
                                     * @throws Exception
                                     */
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//                                        super.channelRead(ctx, msg);
                                        log.info("收到数据：{}",msg);
                                    }
                                });
                            }
                        }
                )
//                7、指定服务器监听的端口
                .bind(9092);

    }
}
